﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

using org.smslib.modem;
using org.smslib.modem.athandler;
using org.smslib;
using System.Text.RegularExpressions;
using System.Diagnostics;
using Microsoft.Practices.EnterpriseLibrary.Logging;
using System.Threading;


namespace SMSCore
{

    public class ATHandler_AnyData_DTGS800 : ATHandler
    {
        public override string getDescription()
        {

            return base.getDescription();
        }
        public override string sendCustomATCommand(string atCommand)
        {
            bool re = IsTrueNum(atCommand);
            return re.ToString();
        }
        public bool IsTrueNum(string num)
        {

            bool isSucc = false;
            getModemDriver().write(String.Format("AT+CDV{0}\r", num));
            string s = getModemDriver().getResponse();

            System.Threading.Thread.Sleep(1000);
            getModemDriver().write(String.Format("AT+CHV0\r"));
            string respond = getModemDriver().getResponse();
            int indexof = respond.IndexOf("VOICE CALL : END : ");
            if (indexof > -1)
            {
                string subString = respond.Substring(indexof + 19, 6);
                //判断响铃时间
                if (subString == "000000")
                {
                    isSucc = false;

                }
                else
                {
                    isSucc = true;

                }
            }

            getModemDriver().write("AT+CHV0\r");
            getModemDriver().clearBuffer();
            //ATH 呼叫挂起

            return isSucc;
        }
        public ATHandler_AnyData_DTGS800(ModemGateway myGateway)
            : base(myGateway)
        {

            //  this.getTerminators()[7] = @"^+CMGS:";
            //  string s = "CSQ: 23(cr)CSQ: 22(cr)RING(CNI:13811878005(cr)RING(cr)CNI:13811878005(cr)CSQ: 21";
            string c = ":CSQ: 30(cr)CNI:13811878005(cr)OK(cr)";

            this.getTerminators()[1] = "\\s*([\\p{ASCII}]|[^\\x00-\\xff])*\\s*OK\\s";

            this.getTerminators()[3] = "\\s*([\\p{ASCII}]|[^\\x00-\\xff])*\\s*ERROR\\s";
            // this.getTerminators()[11] ="CNI:\\d+";
            // this.getTerminators()[13] = "CNI:\\d+";
            // bool s= java.util.regex.Pattern.matches(str, input);
            //Regex r = new Regex(this.getTerminators()[13].ToString());
            //Match m = r.Match(c);




            this.getUnsolicitedResponses()[0] = "CMT";
            this.getUnsolicitedResponses()[1] = "CMGS";
            this.getUnsolicitedResponses()[2] = "RING";
            this.getUnsolicitedResponses()[3] = "CNI";
            this.getUnsolicitedResponses()[4] = "CUSD";
        }
        //public override bool isUnsolicitedResponse(string response)
        //{
        //    int i = findMatchingTerminator(response);
        //    Debug.WriteLine(response);
        //    return isUnsolicitedResponse(i);
        //}
        //public override int findMatchingTerminator(string response)
        //{
        //    int terIndex = base.findMatchingTerminator(response);
        //    return terIndex;
        //}

        //public override AGateway.AsyncEvents processUnsolicitedEvents(string response)
        //{
        //    org.smslib.AGateway.AsyncEvents event2 = org.smslib.AGateway.AsyncEvents.NOTHING;
        //    if (response.IndexOf(getUnsolicitedResponse(0)) >= 0) event2 = org.smslib.AGateway.AsyncEvents.INBOUNDMESSAGE;
        //    else if (response.IndexOf(getUnsolicitedResponse(1)) >= 0) event2 = org.smslib.AGateway.AsyncEvents.INBOUNDSTATUSREPORTMESSAGE;
        //    else if (response.IndexOf(getUnsolicitedResponse(2)) >= 0) event2 = org.smslib.AGateway.AsyncEvents.NOTHING;
        //    else if (response.IndexOf(getUnsolicitedResponse(3)) >= 0) event2 = org.smslib.AGateway.AsyncEvents.INBOUNDCALL;
        //    else if (response.IndexOf(getUnsolicitedResponse(4)) >= 0) event2 = org.smslib.AGateway.AsyncEvents.USSDRESPONSE;
        //    return event2;
        //}
        public override bool deleteMessage(int memIndex, string memLocation)
        {
            //getModemDriver().write("AT+CMGD=_1_\r".Replace("_1_", "" + memIndex));
            //getModemDriver().getResponse();
            return (getModemDriver().isOk());
        }
        public override bool switchStorageLocation(string mem)
        {
            return true;
            //return base.switchStorageLocation(mem);
        }
        public override string getMessageByIndex(int msgIndex)
        {
            // getModemDriver().write("AT+CMGR=" + msgIndex + "\r");
            getModemDriver().clearBuffer();
            getModemDriver().write("AT+SMSR\r");
            return (getModemDriver().getResponse());
        }
        public override string send(string s)
        {

            return base.send(s);
        }
        public override void sync()
        {

        }
        public int SendMesNew(int size, string pdu, string phone, string text)
        {
            int refNo = -1;
            try
            {
                string response = "";
                getModemDriver().clearBuffer();
                getModemDriver().write("AT+CAD?\r");
                response = getModemDriver().getResponse();
                Regex succ = new Regex("\\s*CAD: [01235]");
                if (succ.Match(response).Success)
                {
                    getModemDriver().write("AT+SMSG=1\r");
                    response = getModemDriver().getResponse();
                    if (response.IndexOf("OK") > -1)
                    {
                        getModemDriver().write("AT+SMSS?\r");
                        response = getModemDriver().getResponse();
                        Regex succ2 = new Regex("\\s*SMSS: 3");
                        if (succ2.Match(response).Success)
                        {
                            string result = "";
                            Encoding encodingUTF = Encoding.BigEndianUnicode;
                            byte[] Bytes = encodingUTF.GetBytes(text);
                            byte[] header = new byte[6];
                            byte[] number = Encoding.ASCII.GetBytes(phone);
                            header[0] = 0x07;
                            header[1] = 0x02;
                            header[2] = 0x2c;
                            header[3] = 0x00;
                            header[4] = 0x01;
                            header[5] = byte.Parse(number.Length.ToString());
                            byte[] type = new byte[4];
                            type[0] = 0x2c;
                            type[1] = 0x00;
                            type[2] = 0x08;
                            type[3] = byte.Parse(Bytes.Length.ToString());
                            byte[] all = new byte[header.Length + number.Length + type.Length + Bytes.Length];
                            for (int i = 0; i < header.Length; i++)
                            {
                                result += BitConverter.ToString(header, i, 1);
                            }
                            for (int i = 0; i < number.Length; i++)
                            {
                                result += BitConverter.ToString(number, i, 1);
                            }
                            for (int i = 0; i < type.Length; i++)
                            {
                                result += BitConverter.ToString(type, i, 1);
                            }
                            for (int i = 0; i < Bytes.Length; i++)
                            {
                                result += BitConverter.ToString(Bytes, i, 1);
                            }
                            getModemDriver().write(header);
                            getModemDriver().write(number);
                            getModemDriver().write(type);
                            getModemDriver().write(Bytes);
                            //int count = Bytes.Length / 40;
                            //int ij = 0;
                            //for (; ij < count; ij++)
                            //{
                            //    getModemDriver().write(Bytes.(ij * 40, 40));
                            //    //Console.WriteLine("写" + ij);
                            //    System.Threading.Thread.Sleep(Service.getInstance().getSettings().AT_WAIT);
                            //}
                            //if (40 * (ij) <= result.Length)
                            //{
                            //    //Console.WriteLine("写最后");
                            //    getModemDriver().write(result.Bytes(ij * 40, result.Length - 40 * ij));

                            //}
                            //getModemDriver().write("\r");
                            Thread.Sleep(5000);
                            for (int k = 0; k < 5; k++)
                            {
                                Thread.Sleep(500);
                                try
                                {
                                    getModemDriver().write("AT+SMSS?\r");
                                    response = getModemDriver().getResponse();
                                    if (response.IndexOf("SMSS: 1") > -1)
                                    {
                                        refNo = 1;
                                        break;
                                    }
                                    if (response.IndexOf("SMSS: 2") > -1)
                                    {
                                        refNo = -1;
                                        break;
                                    }
                                }
                                catch
                                {
                                }
                            }
                        }
                    }
                }
            }
            catch
            {

            }
            return refNo;
        }
        public override int sendMessage(int size, string pdu, string phone, string text)
        {
            int refNo = -1;
            return SendMesNew(size, pdu, phone, text);
            try
            {
                string result = "";
                Encoding encodingUTF = Encoding.BigEndianUnicode;
                byte[] Bytes = encodingUTF.GetBytes(text);
                int responseRetries = 0, errorRetries = 0;
                responseRetries = 0;
                string response = "";
                getModemDriver().clearBuffer();
                int sendID = (new Random()).Next(1, 10);
                string s = sendID.ToString();
                //   System.Threading.Thread.Sleep(Service.getInstance().getSettings().AT_WAIT);
                getModemDriver().write("AT+CMGS=" + s + "," + phone + ",,3,");
                //Console.WriteLine("写cmgs!");
                for (int i = 0; i < Bytes.Length; i++)
                {
                    result += BitConverter.ToString(Bytes, i, 1);
                }
                int count = result.Length / 40;
                int ij = 0;
                for (; ij < count; ij++)
                {
                    getModemDriver().write(result.Substring(ij * 40, 40));
                    //Console.WriteLine("写" + ij);
                    System.Threading.Thread.Sleep(Service.getInstance().getSettings().AT_WAIT);
                }
                if (40 * (ij) <= result.Length)
                {
                    //Console.WriteLine("写最后");
                    getModemDriver().write(result.Substring(ij * 40, result.Length - 40 * ij));

                }
                getModemDriver().write("\r");
                try
                {
                    System.Threading.Thread.Sleep(1000);
                    response = getModemDriver().getResponse();
                }
                catch
                {
                    Console.WriteLine("得到发送该消息回应失败!");

                }
                //while (response.Length == 0)
                //{
                //    responseRetries++;
                //    if (responseRetries == Service.getInstance().getSettings().OUTBOUND_RETRIES) throw new GatewayException("Gateway is not responding, max number of retries reached.");
                //    Logger.Write("ATHandler().SendMessage(): Still waiting for response ");
                //    Thread.Sleep(Service.getInstance().getSettings().OUTBOUND_RETRY_WAIT);
                //    response = getModemDriver().getResponse();
                //}

                if (response.Length != 0)
                {
                    Regex succ = new Regex("\\s*CMGS: *(\\d+),1");
                    Regex fail = new Regex("\\s*CMGS: *(\\d+),0");
                    bool hasMatch = false;

                    if (succ.Match(response).Success)
                    {
                        refNo = 1;
                        hasMatch = true;
                    }
                    if (fail.Match(response).Success)
                    {
                        refNo = -1;
                        hasMatch = true;
                    }
                }
            }
            catch
            {
            }

            return refNo;
        }
        //public override string getNetworkRegistration()
        //{
        //    //getModemDriver().write("AT+CREG=1\r");
        //    //getModemDriver().getResponse();
        //    //getModemDriver().write("AT+CREG?\r");
        //    return "Abc";
        //}


        //public override bool isAlive()
        //{
        //    try
        //    {
        //        getModemDriver().write("AT\r");

        //        string response = getModemDriver().getResponse();
        //        if (response.IndexOf("OK") > -1)
        //        {
        //            return getModemDriver().isOk();
        //        }
        //    }
        //    catch
        //    {

        //    }
        //    Console.WriteLine("alive not ");
        //    return false;
        //}
        public override string getSimStatus()
        {
            //getModemDriver().write("AT\r");
            //getModemDriver().getResponse();

            return "OK";
        }
        public override string getNetworkRegistration()
        {

            return "AT+CREG=1,1";
        }
        public override void done()
        {
            Console.WriteLine("done");
            //  base.done();
        }
        public override void echoOff()
        {
            try
            {
                getModemDriver().write("ATE0\r");
                System.Threading.Thread.Sleep(Service.getInstance().getSettings().AT_WAIT);
                // getModemDriver().getResponse();
            }
            catch
            {
            }
        }
        public override string getStorageLocations()
        {
            // string s = base.getStorageLocations();
            return "OK";
        }
        public override bool setVerboseErrors()
        {
            return (getModemDriver().isOk());
        }

        public override bool setIndications()
        {
            return false;
        }

        public override string getModel()
        {
            Console.WriteLine("getModel");
            return base.getModel();
        }
        public override string listMessages(InboundMessage.MessageClasses messageClass)
        {
            if (getGateway().getProtocol() == org.smslib.AGateway.Protocols.PDU)
            {
               getModemDriver().write("AT+SMSC?\r");

            }
            string rs = "0";
            string count = "0";
            try
            {

                rs = getModemDriver().getResponse();
                Regex succ = new Regex("\\s*SMSC: *(\\d+)");
                if (succ.Match(rs).Success)
                {
                    Regex succCount = new Regex("\\s*(\\d+)");
                    Match m = succCount.Match(succ.Match(rs).Value);
                    count = m.Value;
                }
                else
                {
                    rs = getModemDriver().getResponse();
                    Regex succ2 = new Regex("\\s*SMSC: *(\\d+)");
                    if (succ2.Match(rs).Success)
                    {
                        Regex succCount = new Regex("\\s*(\\d+)");
                        Match m = succCount.Match(succ2.Match(rs).Value);
                        count = m.Value;
                    }
                }

            }
            catch (Exception ex)
            {

            }
            return count;
        }
        public override string getBatteryLevel()
        {
            return "OK";
        }

        public override void init()
        {
            try
            {
                getModemDriver().clearBuffer();
                System.Threading.Thread.Sleep(Service.getInstance().getSettings().SERIAL_CLEAR_WAIT);


                //  getModemDriver().getResponse();
                getModemDriver().write("AT+UGSM=0\r");
                System.Threading.Thread.Sleep(Service.getInstance().getSettings().AT_WAIT);
                // getModemDriver().getResponse();
                //getModemDriver().write("AT+CMGF=1\r");
                //System.Threading.Thread.Sleep(Service.getInstance().getSettings().AT_WAIT);

                getModemDriver().write("AT+SMSP=285\r");
                System.Threading.Thread.Sleep(Service.getInstance().getSettings().AT_WAIT);
                ////getModemDriver().write("AT+FST2=3,8000\r");
                ////System.Threading.Thread.Sleep(Service.getInstance().getSettings().AT_WAIT);
                // getModemDriver().getResponse();
                getModemDriver().clearBuffer();
                // base.init();
                Console.WriteLine("init");
            }
            catch (Exception ex)
            {
                Logger.Write(ex);
            }
        }
        public override bool setPduProtocol()
        {
            return true;
            //return base.setPduProtocol();
        }

        public override void reset()
        {
            //try
            //{
            //    getModemDriver().write("\r");


            //    System.Threading.Thread.Sleep(Service.getInstance().getSettings().AT_WAIT);
            //    getModemDriver().write("AT\r");

            //    getModemDriver().getResponse();
            //}
            //catch
            //{
            //}

        }




    }

}
